import {
  IGridDataProviderBaseOptions,
  IGridDataOptions,
  GridDataProviderBase,
  ensureGridDataOptions,
  GridData,
  GridDataType
} from '@quickearth/core'
import GeoTIFF, { fromUrl, fromUrls, fromArrayBuffer, fromBlob } from 'geotiff'
interface ITifGridDataProviderOptions extends IGridDataProviderBaseOptions {
  /**
   * 缺测值，默认为999999
   */
  undef?: number
  /**
   * 数据区域属性
   */
  gridOptions?: IGridDataOptions
}
class TifGridDataProvider extends GridDataProviderBase {
  public meta: any = {}

  constructor(buffer: ArrayBuffer, options: ITifGridDataProviderOptions) {
    super(options)
    this.load(buffer, options)
  }

  private static readTifBuffer = async (buffer: ArrayBuffer) => {
    const tiff = await fromArrayBuffer(buffer)
    const image = await tiff.getImage()
    const reso = image.getResolution()
    const origin = image.getOrigin() as number[]
    const width = image.getWidth()
    const height = image.getHeight()
    const options = {
      xStart: origin[0],
      yStart: origin[1],
      xDelta: reso[0],
      yDelta: reso[1],
      xSize: width,
      ySize: height
    }
    const data = await image.readRasters()
    // debugger
    return { options, data }
  }

  private getDataType = (data: ArrayBuffer) => {
    switch (data.constructor.name) {
      case 'Int8Array':
        return GridDataType.Int8
      case 'Uint8Array':
        return GridDataType.UInt8
      case 'Int16Array':
        return GridDataType.Int16
      case 'Uint16Array':
        return GridDataType.UInt16
      case 'Int32Array':
        return GridDataType.Int32
      case 'Uint32Array':
        return GridDataType.UInt32
      case 'Float32Array':
        return GridDataType.Float32
      case 'Float64Array':
        return GridDataType.Float64
      default:
        throw new Error('不支持的数据类型：' + data.constructor.name)
    }
  }

  private load = (data: ArrayBuffer, options: ITifGridDataProviderOptions) => {
    this.gridOptions = options.gridOptions
    ensureGridDataOptions(this.gridOptions)
    let levelData: GridData[] = []
    const dataType = this.getDataType(data)
    const undef = options.undef ? options.undef : consts.defaultUndef
    const gridData = new GridData(
      dataType,
      this.gridOptions.xSize,
      this.gridOptions.ySize,
      data,
      undef
    )
    levelData.push(gridData)
    this.grids.push(levelData)
  }

  public static fromBuffer = async (
    buffer: ArrayBuffer,
    options: ITifGridDataProviderOptions = {} as any
  ): Promise<TifGridDataProvider> => {
    return TifGridDataProvider.readTifBuffer(buffer)
      .then(res => {
        options.gridOptions = options.gridOptions || res.options
        const provider = new TifGridDataProvider(res.data[0], options)
        return provider
      })
      .catch(err => {
        // debugger
      }) as any
  }

  public static qeName = 'g_tif'
}
export default TifGridDataProvider
